package com.qrxl.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qrxl.common.exception.CustomException;
import com.qrxl.util.JGAssert;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期转换
 *
 * @author
 */
public class DateHandler extends DateUtil {

    /**
     * 系统默认的日期格式化格式
     */
    public final static String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";

    private static final Logger logger = LoggerFactory.getLogger(DateHandler.class);

    /**
     * 获取当前时间距离当天23:59:59多长时间(单位秒)
     *
     * @return
     */
    public static int getCurrentDayTimeDistance() {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
            String endDate = "23:59:59";
            Long endTime = simpleDateFormat.parse(endDate).getTime();
            Long startTime = simpleDateFormat.parse(simpleDateFormat.format(new Date())).getTime();
            return Long.valueOf((endTime - startTime) / 1000).intValue();
        } catch (ParseException e) {
            throw new CustomException("日期解析错误");
        }
    }

    public static int getYear(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    public static int getMonth(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MONTH)+1;
    }

    public static int getDay(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取当前时间距离当月23:59:59多长时间(单位秒)
     *
     * @return int
     */
    public static int getCurrentMonthTimeDistance() {
        Date now = new Date();
        Date endTime = DateHandler.getLastTimeOfMonth();
        return Long.valueOf((endTime.getTime() - now.getTime()) / 1000).intValue();
    }

    /**
     * 根据时间，加减n秒。
     *
     * @param date date
     * @param n    加减的数值
     * @return Date
     */
    public static Date addWithField(Date date, int n, int field) {
        Calendar nowCal = Calendar.getInstance();
        Optional.ofNullable(date).ifPresent(nowCal::setTime);
        nowCal.add(field, n);
        return nowCal.getTime();
    }


    /**
     * 根据时间，加减n分钟。
     *
     * @param basicDate
     * @param minute    >0 加；<0 减
     * @return Date
     * @author xieyuanqing
     * @date:2016年7月8日
     */
    public static Date addWithMinute(Date basicDate, int minute) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(basicDate);
        rightNow.add(Calendar.MINUTE, minute);
        return rightNow.getTime();
    }

    /**
     * 根据时间，加减n小时
     *
     * @param hour 加减n个小时
     */
    public static Date addWithHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    /**
     * 根据时间，加减n天
     *
     * @param day >0 加；<0 减
     */
    public static Date addWithDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 根据时间，加减n年。
     *
     * @param basicDate
     * @param yearNum   >0 加；<0 减
     * @return Date
     * @author xieyuanqing
     * @date:2016年7月8日
     */
    public static Date addWithYear(Date basicDate, int yearNum) {
        if (yearNum == 0) {
            return basicDate;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(basicDate);
        calendar.add(Calendar.YEAR, yearNum);
        return calendar.getTime();
    }

    /**
     * 获取指定日期指定天数的日期
     *
     * @param basicDate
     * @param day       >0 加；<0 减
     * @param pattern   格式化类型
     * @return
     * @author yuanchang
     */
    public static String getMonthAndDay(Date basicDate, int day, String pattern) {
        // 定义输出日期格式
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(basicDate);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return sdf.format(calendar.getTime());
    }

    /**
     * 只给门禁接口获取居民数据使用
     * 没办法,前一个人这样写的。
     * 我猜测的目的是,日期会出现三个格式
     * 有点坑，有点坑，有点坑
     *
     * @param dateStr
     * @return
     */
    @Deprecated
    public static Date parseDate1or8(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        //三种字符串分别处理
        //"2016-10-29 15:48:18"
        if (dateStr.length() == 19) {
            return DateHandler.parseDate(dateStr, 1);
        }
        //"2016-10-29 15:48:18.288548"
        if (dateStr.length() > 23) {
            return DateHandler.parseDate(dateStr.substring(0, 23), 8);
        }
        //"2016-10-29 15:48:18.288"
        else {
            return DateHandler.parseDate(dateStr, 8);
        }
    }

    /**
     * 解析成系统默认格式的日期
     * yyyy-MM-dd HH:mm:ss.SSS
     *
     * @param dateStr
     * @return
     */
    public static Date parseDefaultDate(String dateStr) {
        return parseDate(dateStr, 8);
    }

    /**
     * 日期解析（注意当格式化异常是返回null）
     *
     * @param dateStr
     * @param type
     * @return
     */
    public static Date parseDate(String dateStr, int type) {
        String format = null;
        switch (type) {
            case 1:
                format = "yyyy-MM-dd HH:mm:ss";
                break;

            case 2:
                format = "yyyy年MM月dd日";
                break;

            case 3:
                format = "yyyy年MM月dd日 HH时mm分ss秒";
                break;

            case 4:
                format = "yyyy.MM.dd.";
                break;

            case 5:
                format = "yyyy-MM-dd";
                break;

            case 6:
                format = "MM月dd日";
                break;

            case 7:
                format = "yyyy年MM月dd日 HH时mm分";
                break;

            case 8:
                format = "yyyy-MM-dd HH:mm:ss.SSS";
                break;
            default:
        }
        try {
            return parse(dateStr, format);
        } catch (ParseException e) {
            logger.error("解析异常", e);
        }
        return null;
    }

    /**
     * @param date
     * @return String
     * @Description: 默认格式化yyyy-MM-dd HH:mm:ss
     * @author caichenggang
     * @date:2015年9月17日
     */
    public static String parseToString(Date date) {
        if (date == null) {
            return null;
        }
        return format(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 日期格式转换
     *
     * @param date
     * @param type
     * @return
     */
    public static String translateToString(Date date, int type) {
        if (date == null) {
            return null;
        }
        String format = null;
        switch (type) {
            case 1:
                format = "yyyy-MM-dd HH:mm:ss";
                break;

            case 2:
                format = "yyyy年MM月dd日";
                break;

            case 3:
                format = "yyyy年MM月dd日 HH时mm分ss秒";
                break;

            case 4:
                format = "yyyy.MM.dd.";
                break;

            case 5:
                format = "yyyy-MM-dd";
                break;

            case 6:
                format = "MM月dd日";
                break;

            case 7:
                format = "yyyy年MM月dd日 HH时mm分";
                break;
            case 8:
                format = "yyyyMMddHHmmss_SSS";
                break;
            case 9:
                format = "yyyyMMdd";
                break;
            case 10:
                format = "yyyy-MM-dd HH:mm:ss.SSS";
                break;
            case 11:
                format = "yyyy年MM月";
                break;
            default:
        }
        return format(date, format);
    }

    /**
     * 日期格式转换
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date translateToDate(String date) throws ParseException {
        return parse(date, "yyyy-MM-dd 24HH:mm:ss");
    }

    /**
     * 距今剩余天数
     *
     * @param date
     * @return
     */
    public static int getLastDayFromCurrent(Date date) {
        JGAssert.notNull(date, "日期不能为空");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        Calendar calNow = Calendar.getInstance();
        long mills = cal.getTimeInMillis() - calNow.getTimeInMillis();
        return (int) (mills / (1000 * 3600 * 24));
    }

    /**
     * 当天日期 比如2018-08-08
     *
     * @return
     */
    public static String getNowDate() {
        return format(new Date(), "yyyy-MM-dd");
    }

    /**
     * @return String
     * @Description: 得到当前时间，yyyy-MM-dd HH:mm:ss.SSS
     * @author xieyuanqing
     * @date:2015年12月26日
     */
    public static String getNowAllDate() {
        return format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    /**
     * 比较两个时间的时间差（返回小时）
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Long calculateTime(Date date1, Date date2) {

        Long date3 = date1.getTime() - date2.getTime();
        //计算出小时数
        Long diff = Math.abs(date3) / 1000 / 60 / 60;

        return diff;
    }

    /**
     * 比较两个时间的天数
     *
     * @param date1 时间大的
     * @param date2 时间小的
     * @return
     */
    public static Integer calculateTimeByDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return null;
        }

        Long date3 = date1.getTime() - date2.getTime();
        if (date3 < 0) {
            return null;
        }
        //计算出天数
        Integer diff = Long.valueOf(Math.abs(date3) / 1000 / 60 / 60 / 24).intValue();
        return diff;
    }

    /**
     * 比较两个时间的天数(返回不包含系统配置的节假日时间 的天数)
     *
     * @param endDate   时间大的
     * @param startDate 时间小的
     * @param jsonArray 系统配置json:[{"startTime":"2019-05-01","endTime":"2019-05-04","dayNumber":"4","dateName":"劳动节"}]
     * @return 不包含节假日的天数
     */
    public static Integer calculateTimeFilterByFestival(Date endDate, Date startDate, JSONArray jsonArray) {
        if (endDate == null || startDate == null) {
            return null;
        }
        //时间差
        Integer diff;
        Long date3 = endDate.getTime() - startDate.getTime();
        if (date3 < 0) {
            logger.info("时间比较错误:date1不能小于date2");
            return null;
        }
        //计算出天数
        diff = Long.valueOf(date3 / 1000 / 60 / 60 / 24).intValue();
        if (jsonArray == null) {
            return diff;
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String startTime = jsonObject.getString("startTime");
            String endTime = jsonObject.getString("endTime");
            if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
                continue;
            }
            //节假日开始时间
            Long holidayStartDate = parseDate(jsonObject.getString("startTime"), 5).getTime();
            //节假日结束时间(下一天的开始时间)
            Long holidayEndDate = addWithDay(parseDate(jsonObject.getString("endTime"), 5), 1).getTime();
            //还没到节日或节日已过
            if (holidayStartDate > endDate.getTime() || holidayEndDate < startDate.getTime()) {
                continue;
            }
            //在startDate和endDate时间内，完全包含节假日时间
            if (holidayStartDate > startDate.getTime() && holidayEndDate < endDate.getTime()) {
                logger.info(jsonObject.getString("dateName"));
                //需要去除的节假日天数
                long dayLong = holidayEndDate - holidayStartDate;
                Integer festivalNumber = Long.valueOf(dayLong / 1000 / 60 / 60 / 24).intValue();
                return diff - festivalNumber;
            }
            //在startDate和endDate时间内，没有完全包含节假日时间
            if (holidayStartDate > startDate.getTime() && holidayEndDate >= endDate.getTime()) {
                logger.info(jsonObject.getString("dateName"));
                ///需要去除的节假日天数
                long dayLong = endDate.getTime() - holidayStartDate;
                Integer festivalNumber = Long.valueOf(dayLong / 1000 / 60 / 60 / 24).intValue();
                return diff - festivalNumber;
            }
        }
        return diff;
    }


    public static Integer getAgeByDate(Date birthDay) {
        if (birthDay == null) {
            return null;
        }
        Calendar birthDayCal = Calendar.getInstance();
        //获取当前系统时间
        Calendar cal = Calendar.getInstance();

        birthDayCal.setTime(birthDay);
        //如果出生日期大于当前时间，则抛出异常
        if (cal.before(birthDayCal)) {
            return 0;
        }
        //取出系统当前时间的年、月、日部分
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);

        //将日期设置为出生日期
        cal.setTime(birthDay);
        //取出出生日期的年、月、日部分
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        //当前年份与出生年份相减，初步计算年龄
        int age = yearNow - yearBirth;
        //当前月份与出生日期的月份相比，如果月份小于出生月份，则年龄上减1，表示不满多少周岁
        if (monthNow <= monthBirth) {
            //如果月份相等，在比较日期，如果当前日，小于出生日，也减1，表示不满多少周岁
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }

    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     *
     * @param str1 时间参数 1 格式：1990-01-01 12:00:00
     * @param str2 时间参数 2 格式：2009-01-01 12:00:00
     * @return String 返回值为：xx天xx小时xx分xx秒
     */
    public static String getDistanceTime(String str1, String str2) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date one;
        Date two;
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {
            one = df.parse(str1);
            two = df.parse(str2);
            long time1 = one.getTime();
            long time2 = two.getTime();
            long diff;
            if (time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (ParseException e) {
            logger.error("解析异常", e);
        }
        return day + "天" + hour + "小时" + min + "分" + sec + "秒";
    }

    /**
     * UTC时间转本地时间
     *
     * @param utc 例如："2014-08-23T09:20:05Z"
     * @return
     */
    public static String utcParseLocalDate(String utc) {
        SimpleDateFormat df = getSdf("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        try {
            return format(df.parse(utc), "yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {
            throw new CustomException("UTC转本地时间失败！");
        }
    }

    /**
     * 获取当前时间的凌晨时间00:00:00
     */
    public static Date getZeroTime() {
        return getZeroTime(new Date());
    }

    /**
     * 把传入的时间的时分秒毫秒设置为00:00:00.0
     *
     * @param bizTime
     * @return
     */
    public static Date getZeroTime(Date bizTime) {
        if (bizTime == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(bizTime);
        return getDayStartTime(calendar);
    }

    /**
     * 获取当前时间的最后时间23:59:59.999
     */
    public static Date getLastTime() {
        return getLastTime(new Date());
    }

    /**
     * 把传入的时间的时分秒毫秒设置为23:59:59.999
     *
     * @param bizTime
     * @return
     */
    public static Date getLastTime(Date bizTime) {
        if (bizTime == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(bizTime);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取当月时间的最后时间23:59:59.999
     */
    public static Date getLastTimeOfMonth() {
        Date lastTime = DateHandler.getLastTime();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(lastTime);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 时间，年月日时
     *
     * @param date date
     */
    public static Date getDateWithHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 当前时间，年月日时
     */
    public static Date getDateWithHour() {
        return getDateWithHour(new Date());
    }

    /**
     * 获取最近N天的开始时间
     *
     * @param n 最近n天
     */
    public static Date getNDateTime(int n) {
        Date today = new Date();
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(today);
            calendar.add(Calendar.DATE, -n);
        } catch (Exception e) {
            e.printStackTrace();
        }
        setZeroFromHourToMillisecond(calendar);
        return calendar.getTime();
    }

    /**
     * 获取当月第一天的凌晨时间
     */
    public static Date getMonthFirstDayZeroTime() {
        Calendar calendar = getCalendar();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        setZeroFromHourToMillisecond(calendar);
        return calendar.getTime();
    }


    /**
     * 指定年月
     */
    public static Calendar getWithField(int year, int month) {
        Calendar calendar = getCalendar();
        if (year < 0 || month < 0) {
            return calendar;
        }
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        return calendar;
    }

    /**
     * 设置日历指定字段的最大值
     */
    public static Calendar setMax(Calendar calendar, int... fields) {
        for (int field : fields) {
            calendar.set(field, calendar.getActualMaximum(field));
        }
        return calendar;
    }

    /**
     * 通过日期实例获取当天开始时间 00:00:00.000
     */
    private static Date getDayStartTime(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 通过日期实例获取当天结束时间 23:59:59.999
     */
    private static Date getDayEndTime(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    private static void setZeroFromHourToMillisecond(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    private static Calendar getCalendar() {
        return Calendar.getInstance();
    }

    public static void main(String[] args) {
       /* Date date1 = parseDate1or8("2016-10-29 15:48:18.288548");
        Date date2 = parseDate1or8("2016-10-29 15:48:18.288");
        Date date3 = parseDate1or8("2016-10-29 15:48:18.28");
        Date date4 = parseDate1or8("2016-10-29 15:48:18");
        System.out.println("data1" + date1);
        System.out.println("data2" + date2);
        System.out.println("data3" + date3);
        System.out.println("data4" + date4);*/
        /*if (DateHandler.parseDefaultDate("2017-01-01 00:00:00.000").compareTo(new Date()) < 0) {
            System.out.printf("2017 before");
        } else {
            System.out.printf("2017 after");
        }*/
//        System.out.println(DateHandler.getDateByYear(new Date(), -60));//   19851010

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, 8);
        int dayNum = cal.getActualMaximum(Calendar.DATE);
        System.out.println(cal.getTime() + "  " + dayNum);

    }

    /**
     * 判断两个日期是否相等
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSame(Date date1, Date date2) {
        if (null == date1 && null == date2) {
            return true;
        } else if (null == date1 || null == date2) {
            return false;
        }
        return date1.getTime() == date2.getTime();
    }

    /**
     * 根据传入的时间获取该月的每一天
     *
     * @param date 时间
     * @return list 该月的每一天时间字符串列表
     */
    public static List<Date> getDayByMonth(Date date) {
        List<Date> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            String aDate = null;
            if (month < 10 && i < 10) {
                aDate = String.valueOf(year) + "-0" + month + "-0" + i;
            }
            if (month < 10 && i >= 10) {
                aDate = String.valueOf(year) + "-0" + month + "-" + i;
            }
            if (month >= 10 && i < 10) {
                aDate = String.valueOf(year) + "-" + month + "-0" + i;
            }
            if (month >= 10 && i >= 10) {
                aDate = String.valueOf(year) + "-" + month + "-" + i;
            }

            list.add(parseDate(aDate, 5));
        }
        return list;
    }

}


/**
 * @author zhenwei.liu created on 2013 13-8-29 下午5:35
 * @version $Id$
 */
class DateUtil {

    /**
     * 锁对象
     */
    private static final Object LOCK_OBJ = new Object();

    /**
     * 存放不同的日期模板格式的sdf的Map
     */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     * @return
     */
    public static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);

        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (tl == null) {
            synchronized (LOCK_OBJ) {
                tl = sdfMap.get(pattern);
                if (tl == null) {
                    // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                    //System.out.println("put new sdf of pattern " + pattern + " to map");

                    // 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new SimpleDateFormat
                    tl = new ThreadLocal<SimpleDateFormat>() {

                        @Override
                        protected SimpleDateFormat initialValue() {
                            //System.out.println("thread: " + Thread.currentThread() + " init pattern: " + pattern);
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, tl);
                }
            }
        }

        return tl.get();
    }

    /**
     * 是用ThreadLocal<SimpleDateFormat>来获取SimpleDateFormat,这样每个线程只会有一个SimpleDateFormat
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String format(Date date, String pattern) {
        return getSdf(pattern).format(date);
    }

    public static Date parse(String dateStr, String pattern) throws ParseException {
        return getSdf(pattern).parse(dateStr);
    }

    /**
     * 通过秒数，计算 天、小时、分钟、秒
     *
     * @param mss 秒数
     */
    public static String formatDateTime(long mss) {
        String dateTimes;
        long days = mss / (60 * 60 * 24);
        long hours = (mss % (60 * 60 * 24)) / (60 * 60);
        long minutes = (mss % (60 * 60)) / 60;
        long seconds = mss % 60;
        if (days > 0) {
            dateTimes = days + "天" + hours + "小时" + minutes + "分钟"
                    + seconds + "秒";
        } else if (hours > 0) {
            dateTimes = hours + "小时" + minutes + "分钟"
                    + seconds + "秒";
        } else if (minutes > 0) {
            dateTimes = minutes + "分钟"
                    + seconds + "秒";
        } else {
            dateTimes = seconds + "秒";
        }

        return dateTimes;
    }

    /**
     * 获取当前时间是今天的第几分钟
     *
     * @return
     */
    public static int getMinutesOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE);
    }

    /**
     * date转为long
     *
     * @param date input
     * @return output
     */
    public static Long dateConvertLong(Date date) {
        if (date == null) {
            return null;
        } else {
            return date.getTime();
        }
    }

    /**
     * 日期计算
     * @param baseDate
     * @param days 需要加减天数
     * @return
     */
    public static Date calcDate(Date baseDate,int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(baseDate);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + days);//让日期加1
        return calendar.getTime();
    }
}
